RS40B - uživatelský manuál


2.6.4 - Podmínky a cykly

Díky podmínkám můžete na základě dat rozhodovat co bude aplikace dělat. Cykly nám zase umožní dělat nějaké akce opakovaně a tak výrazně zefektivní práci při programování.

Podmínka if

Příkaz if umožňuje testování podmínky (například zda se dvě proměnné rovnají) a podle jejího výsledku, rozvětvení kódu na různé části.

Nejjednoduší podoba podmínky if vypadá takto:

if (výraz)
  <instrukce>
endif

U příkazu if, nemusí být výraz v závorce. Avšak u složitějších výrazů je lepší závorky použít. Výraz může být libovolný, obvykle se však jedná o výraz který obrahuje relační operátor. Je-li výraz u příkazu if vyhodnocen jako pravda (například 1==1), jsou provedeny instrukce až po ukončení příkazem endif, ten musí vždy podmínku ukončovat. Pokud je výraz vyhodnocen jako nepravda (1==2) je příkaz přeskočen.

Příklad:
Lokální data:
num cislo1, cislo2


01:begin
02:  putln("Zadejte číslo 1: ")
03:  get(cislo1)
04:  putln("Zadejte číslo 2: ")
05:  get(cislo2)

06:  if cislo1 < cislo2
07:  putln("Číslo 1 je menší než číslo 2")
08:  endif

09:  if cislo1 > cislo2
10:  putln("Číslo 1 je větší než číslo 2")
11:  endif

12:  if cislo1 == cislo2
13:  putln("Číslo 1 je menší než číslo 2")
14:  endif
15:end

Tento jednoduchý program porovnává dvě čísla, která jsme si deklarovaly na prvním řádku. Pomocí tří podmínek if testuje, zda se čísla, která uživatel zadá z klávesnice, rovnají nebo jestli jsou větší či menší a na základě toho poté vypíše výsledek na obrazovku. Všimněte si řádku 12, kde pro porovnání používáme dvou znaků rovno, pokud by byl použit jen jeden, podmínka by se vyhodnotila vždy kladně, jelikož by se číslu 1 přiřadila hodnota čísla 2.

Kauzule else, elseif

Často je program třeba větvit ve dvou směrech. Jedním způsobem, když je podmínka pravdivá, a jinak, když je nepravdivá. Else nám vlastně říká, že i v případě nepravdivé podmínky se má něco udělat. Podobný význam má i příkaz elseif, ten testuje další podmínku, pokud není splněna podmínka původní. Podmínek elseif může být konečně mnoho a jsou nepovinné, stejně jako není povinná podmínka else.

Vyhodnocování podmínek probíhá do té doby, než se některá vyhodnotí jako pravdivá (true). Pak se provedou následující příkazy. Další podmínky se již nevyhodnocují. Pokud se žádná podmínka nevyhodnotí jako pravdivá, pak se provedou příkazy za podmínkou else (pokud podmínka else existuje). Else se umisťuje vždy na konec. Je to to samé, jako by jste uvedli na konci elseif true.

Příklad
Lokální data:
num x
num cislo = 7


01:begin
02:  putln("Myslim si cislo v rozsahu 1-10, hádej jaké: ")
03:  get(x)

04:  if !((x < 1) or (x > 10))

05:    if x==cislo
06:      putln("Správně, uhádnul jsi.")
07:    elseif x>cislo
08:      putln("Příliš vysoké.")
09:    else
10:      putln("Moc nízké.")
11:    endif

12:  else
13:    putln("Zadal jsi cislo mimo požadovaný rozsah...")
14:  endif
15:end

Zde jsme si ukázaly program hádání čísel, kderý demonstruje použití podmínek if, elseif, else. Nejprve je uživatel vyzván aby zadal číslo od 1 do 10. Program poté zjišťuje, zda bylo opravdu zadáno číslo v požadovaném rozsahu. Tato podmínka je testována na řádku číslo 4. Tento výraz zjistí, zda je číslo mimo rozsah a poté jej za pomocí negace vyhodnotí. Tento výraz lze stejným způsobem vyhodnotit i bez použití negace, zkuste nad tím trochu zapřemýšlet.
Pokud je zadané číslo v požadovaném rozsahu, bude vyhodnoceno zda je rovno, větší či menší než číslo požadované. To vyhodnocuje vnořená podmínka if. Pokud není číslo v daném rozsahu, bude provedena podmínka else.

Přepínač switch

Příkazy if se mohou stát poněkud matoucí, pokud jsou do sebe zanořeny příliš hluboko. Proto jazyk VAL3 nabízí alternativu v podobě příkazu switch, který je schopen větvení podle několika hodnot.

Na základě argumentu za klíčovým slovem switch přeskočí program na návěstí case se stejnou hodnotou jakou má výraz za switch a pokračuje vykonáváním příkazů za ním až do klíčového slova break, které ukončuje provádění příkazu switch.
Přepínač switch může obsahovat návěstí default, na které program skočí tehdy, když argument za klíčovým slovem switch neodpovídá hodnotě za žádným návěstím case. Použití příkazu default není povinné.

Obecná podoba příkazu switch je následující:

switch vyraz
  case hodnota1
    <instrukce>
    break

  case hodnota2
    <instrukce>
    break

  default
    <instrukce>
    break
endswitch

Pokud na konci příkazu case nebude žádný příkaz break, přejde provádění programu k příkazům na dalším case. To může být někdy nezbytné, ale obvykle se jedná o chybu. Jestliže se ponechá prováděné programu k dalšímu příkazu case, je dobrým zvykem připojit krátký komentář, že se nejedná o opomenutí.

Příklad
Lokální data:
num den


01:begin
02:  put("Zadej číslo dne v týdnu: ")
03:  get(den)

04:  switch den

05:    case 1
06:      putln("Pondělí")
07:      break

08:    case 2
09:      putln("Úterý")
10:      break

11:    case 3
12:      putln("Středa")
13:      break

14:    case 4
15:      putln("Čtvrtek")
16:      break

17:    case 5
18:      putln("Pátek")
19:      break

20:    case 6
21:      putln("Sobota")
22:      break

23:    case 7
24:      putln("Neděle")
25:      break

26:    default
27:      putln("Takový den v týdnu neexistuje!")
28:      break

29:  endswitch
30:end

Program uživatele požádá, aby zadal číslo dne v týdnu. Poté číslo předá příkazu switch, který vyhodnotí o který den se jedná. V případě, že bylo zadané jiné číslo, vykoná se příkaz default.

Cyklus for

Pomocí cyklů můžeme vykonávat nějakou činnost opakovaně. Podívejme se na cyklus for.

for <vyraz> = <hodnota1> to <hodnota2> step <krok>
  <instrukce>
endFor

Parametry:

Cyklus for provádí příkazy v těle cyklu tak dlouho, dokud platí podmínka. Tato podmínka může být jakýkoliv výraz vracející celočíselnou hodnotu. Podmínka se vyhodnocuje před každým začátkem cyklu. Pokud se hned na poprvé vyhodnotí jako false, pak tělo cyklu neproběhne ani jednou.

Příklad
Lokální data:
num x


01:begin
02:  for x = 0 to 10

03:    if (x % 2) == 0
04:      put("Sude cislo: ")
05:      putln(x)
06:    endIf

07:  endFor


08:  for x = 0 to 10 step 2

09:    put("Sude cislo: ")
10:    putln(x)

11:  endFor
12:end

Zde můžeme vidět příklad použití dvou různých cyklů for, jejichž funkce je ovšem stejná. První cyklus, začínající na řádku 2, inkrementuje proměnnou x od nuly do deseti. Aby jsme zjistily, zda je číslo sudé, použijeme zbytek po celočíselném dělení 2. Pokud je zbytek roven nule, je číslo sudé. V druhém případě jsme inkrementovaly proměnnou x po kroku 2, tedy odpadá nutnost testovat číslo na jeho sudost.

Cyklus while

Prostřednictvím cyklu while se opakovaně provádí sekvence instrukcí, dokud je počáteční podmínka pravdivá. Pokud je počáteční podmínka vyhodnocena jako nepravda, nebude cyklus proveden ani jednou.

příklad:
Lokální data:
num x=3
num cislo


01:begin
02:  putln("Myslím si číslo od 0 do 10, hádej jaké.")

03:  while cislo!=x
04:    get(cislo)

05:    if cislo < x
06:      putln("Myslím si větší číslo.")
07:    elseif cislo > x
08:      putln("Myslím si menší číslo.")
09:    endIf

10:  endWhile

11:  putln("Správně, uhodl jsi.")
12:end

Cyklus se bude opakovat, dokud uživatel neuhádne číslo, to je testováno na řádku 3. Po kažném špatném hádání, je uživateli napovězeno, zda je číslo menší či větší, to je ošetřeno podmínkou if, kterou by jste již měli ovládat.

Cyklus do...until

Má téměř stejnou funkci jako cyklus while, s tím rozdílem, že cyklus do...until bude proveden vždy minimálně jednou.

Rozdíl si můžeme demonstrovat na předchozím příkladu. Pokud bychom chtěli, aby hádané číslo bylo 0, smyčka while by se nevykonala ani jednou. Protože proměnná x, má implicitně hodnotu 0. Tedy nebyla by splněna podmínka pro vykonání cyklu a ten by nebyl vykonán ani jednou. Tento problém lze vyřešit jednoduše použitím cyklu do...while jak si ukážeme na příkladu.

příklad
Lokální data:
num x=0
num cislo


01:begin
02:  putln("Myslím si číslo od 0 do 10, hádej jaké.")

03:  do
04:    get(cislo)

05:    if cislo < x
06:      putln("Myslím si větší číslo.")
07:    elseif cislo > x
08:      putln("Myslím si menší číslo.")
09:    endIf

10:  until cislo!=x

11:  putln("Správně, uhodl jsi.")
12:begin

Jak je vidět, problém byl vyřešen pouze změnou na řádku 3 a 10, zbylá část kódu zůstává nezměněná, protože cykly while a do...until se od sebe funkčně nijak neliší.